﻿using Coldairarrow.Entity.BackStage.ConsumeChats;
using Coldairarrow.Entity.BackStage.Platform;
using Coldairarrow.Entity.Base_AutoReplys;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.FrontStage.UserData;
using Coldairarrow.Util;
using Coldairarrow.Util.DTO;
using Coldairarrow.Util.DTO.OnlineChat;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace Coldairarrow.Business.BackStage.ConsumeChats
{
    public class ChatRoomBusiness : BaseBusiness<ChatRoom>, IChatRoomBusiness, ITransientDependency
    {
        readonly string userDefaultHeadImg = "http://qnmzptapi.xazkrj.cn/Upload/HeadPort/dhead.jpg";
        readonly string KfDefaultHeadImg = "/HeadImg/kefu002.png";
        public ChatRoomBusiness(IDbAccessor repository)
            : base(repository)
        {
        }

        #region 外部接口

        public async Task<PageResult<ChatRoom>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<ChatRoom>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<ChatRoom, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<ChatRoom> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(ChatRoom data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(ChatRoom data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        /// <summary>
        /// 后台——获取首页统计数据
        /// </summary>
        /// <returns></returns>
        public  List<object> GetUserLogSumDTO()
        {
            List<object> res = new List<object>();
            for (var i = 0; i < 5; i++)
            {
                int count = GetChatUserSumData(i);
                string sName = "";
                if (i == 0)
                {
                    sName = "今日";
                }
                else if (i == 1)
                {
                    sName = "近七天";
                }
                else if (i == 2)
                {
                    sName = "本月";
                }
                else if (i == 3)
                {
                    sName = "近半年(今年内)";
                }
                else if (i == 4)
                {
                    sName = "今年";
                } 
   
                var obj = new {
                 Name = sName,
                 ChatNum = count
                };

                res.Add(obj);
            }

            return res;
        }

        /// <summary>
        /// 后台——获取平台下拉
        /// </summary>
        /// <returns></returns>
        public async Task<List<SelectDTO>> GetPlatformListAsync()
        {
            var list = await Service.GetIQueryable<Base_Platform>().Select(m =>
            new SelectDTO
            {
                Text = m.Name,
                Val = m.Sort.ToString()
            }).ToListAsync();


            return list;
        }

        /// <summary>
        /// 后台——获取所有历史客服列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<SelectDTO>> GetCSSeverListAsync(GetCSSeversInput input)
        {
            List<SelectDTO> res = new List<SelectDTO>();
            if (input.PClassId >= 0)
            {
                #region//获取时间段内所有房间Id
                res = await (from a in Service.GetIQueryable<ChatContent>()
                    .WhereIf(s => s.CreateTime >= input.StartTime, input.StartTime.HasValue)
                    .WhereIf(s => s.CreateTime < input.EndTime, input.EndTime.HasValue)
                             join b in GetIQueryable().Where(m => m.ClassId == input.PClassId) on a.RoomId equals b.Id
                             join c in Service.GetIQueryable<ChatRoomCSUser>() on b.Id equals c.RoomId
                             join e in Service.GetIQueryable<Base_User>() on c.ConstmeServerId equals e.Id
                             select new SelectDTO
                             {
                                 Text = e.RealName,
                                 Val = e.Id
                             }).Distinct().ToListAsync();
                #endregion
            }

            return res;
        }

        /// <summary>
        /// 后台——根据平台类型和客服Id获取用户房间列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<TheRoomDTO>> GetTheRoomListAsync(PageInput<GetRoomListInput> input)
        {
            PageResult<TheRoomDTO> res = new PageResult<TheRoomDTO>();
            res.Total =0;
            res.Data = new List<TheRoomDTO>();

            var search = input.Search;
            List<TheRoomDTO> dList = new List<TheRoomDTO>();

            if (!search.ConsumeServerId.IsNullOrEmpty())
            {
                //获取房间列表
                var rooms = await (from a in Service.GetIQueryable<ChatContent>()
                 .WhereIf(s => s.CreateTime >= search.StartTime, search.StartTime.HasValue)
                 .WhereIf(s => s.CreateTime < search.EndTime, search.EndTime.HasValue)
                                   join b in GetIQueryable() on a.RoomId equals b.Id
                                   join c in Service.GetIQueryable<ChatRoomCSUser>().Where(s => s.ConstmeServerId.Equals(search.ConsumeServerId)) on b.Id equals c.RoomId
                                   join e in Service.GetIQueryable<Base_User>() on c.ConstmeServerId equals e.Id
                                   join f in Service.GetIQueryable<BTB_StaffUser>() on b.UserId equals f.id into bf
                                   from f in bf.DefaultIfEmpty()
                                   select new
                                   {
                                       RId = b.Id,
                                       RName = b.ChatRoot_Name,
                                       UId = b.UserId,
                                       UHeadImg = f.HeadPortrait,
                                       UheadType = f.HeadType,
                                       UName = f.NickName,
                                       MSTime = a.CreateTime
                                   }).GroupBy(s => new { s.RId, s.RName, s.UId, s.UHeadImg, s.UheadType, s.UName }).Select(m =>
                                        new
                                        {
                                            m.Key.RId,
                                            m.Key.RName,
                                            m.Key.UId,
                                            m.Key.UHeadImg,
                                            m.Key.UheadType,
                                            m.Key.UName,
                                            MSTime = m.Max(s => s.MSTime)
                                        }).ToListAsync();


                res.Total = rooms.Count;

                int skipCount = input.PageRows * (input.PageIndex - 1);
                var list = rooms.OrderByDescending(n => n.MSTime).Skip(skipCount).Take(input.PageRows).ToList();
                foreach (var item in list)
                {
                    TheRoomDTO rModel = new TheRoomDTO();
                    rModel.RoomId = item.RId;
                    if (item.UName.IsNullOrEmpty())
                    {
                        rModel.UserId = "USE" + item.UId;
                        rModel.RoomName = "游客"+item.UId.Substring(item.UId.Length - 5);
                        rModel.HeadType = 1;
                        rModel.HeadImg = userDefaultHeadImg;
                    }
                    else
                    {
                        rModel.UserId = "USE" + item.UId;
                        rModel.RoomName = item.UName;
                        rModel.HeadImg = item.UHeadImg.IsNullOrEmpty() ? userDefaultHeadImg : item.UHeadImg;
                        rModel.HeadType =item.UHeadImg.IsNullOrEmpty() ? 1 : item.UheadType;

                    }

                    //获取房间最新消息
                    var message = await Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId)).OrderByDescending(m => m.CreateTime).FirstOrDefaultAsync();
                    if (!message.IsNullOrEmpty())
                    {
                        rModel.MSTime = message.CreateTime;
                        rModel.messageType = message.MessageType;
                        rModel.NewMassage = message.MessageContent;
                        if (rModel.messageType == 12 || rModel.messageType == 11)
                        {
                            rModel.NewMassage ="[自动回复]";
                        }
                    }

                    //获取房间客服未读消息数量
                    rModel.MSCount =  Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId) && x.MessageType != 10).Count();
                    dList.Add(rModel);
                }

                #region
                /* 按平台筛选
                if (search.PClassId >=0 && !search.ConsumeServerId.IsNullOrEmpty())
                {
                    //获取房间列表
                    var rooms = await (from a in Service.GetIQueryable<ChatContent>()
                     .WhereIf(s => s.CreateTime >= search.StartTime, search.StartTime.HasValue)
                     .WhereIf(s => s.CreateTime < search.EndTime, search.EndTime.HasValue)
                                       join b in GetIQueryable().Where(m => m.ClassId == search.PClassId) on a.RoomId equals b.Id
                                       join c in Service.GetIQueryable<ChatRoomCSUser>().Where(s => s.ConstmeServerId.Equals(search.ConsumeServerId)) on b.Id equals c.RoomId
                                       join e in Service.GetIQueryable<Base_User>() on c.ConstmeServerId equals e.Id
                                       join f in Service.GetIQueryable<BTB_StaffUser>() on b.UserId equals f.id into bf
                                       from f in bf.DefaultIfEmpty()
                                       select new
                                       {
                                           RId = b.Id,
                                           RName = b.ChatRoot_Name,
                                           UId = b.UserId,
                                           UHeadImg = f.HeadPortrait,
                                           UheadType = f.HeadType,
                                           UName = f.NickName,
                                           MSTime = a.CreateTime
                                       }).GroupBy(s => new { s.RId, s.RName, s.UId, s.UHeadImg, s.UheadType, s.UName }).Select(m =>
                                            new
                                            {
                                                m.Key.RId,
                                                m.Key.RName,
                                                m.Key.UId,
                                                m.Key.UHeadImg,
                                                m.Key.UheadType,
                                                m.Key.UName,
                                                MSTime = m.Max(s => s.MSTime)
                                            }).ToListAsync();


                    res.Total = rooms.Count;

                    int skipCount = input.PageRows * (input.PageIndex - 1);
                    var list = rooms.OrderByDescending(n => n.MSTime).Skip(skipCount).Take(input.PageRows).ToList();
                    foreach (var item in list)
                    {
                        TheRoomDTO rModel = new TheRoomDTO();
                        rModel.RoomId = item.RId;
                        if (item.UName.IsNullOrEmpty())
                        {
                            rModel.UserId = "USE" + item.UId;
                            rModel.RoomName = "游客"+item.UId.Substring(item.UId.Length - 5);
                            rModel.HeadType = 1;
                            rModel.HeadImg = userDefaultHeadImg;
                        }
                        else
                        {
                            rModel.UserId = "USE" + item.UId;
                            rModel.RoomName = item.UName;
                            rModel.HeadImg = item.UHeadImg.IsNullOrEmpty() ? userDefaultHeadImg : item.UHeadImg;
                            rModel.HeadType =item.UHeadImg.IsNullOrEmpty() ? 1 : item.UheadType;

                        }

                        //获取房间最新消息
                        var message = await Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId)).OrderByDescending(m => m.CreateTime).FirstOrDefaultAsync();
                        if (!message.IsNullOrEmpty())
                        {
                            rModel.MSTime = message.CreateTime;
                            rModel.messageType = message.MessageType;
                            rModel.NewMassage = message.MessageContent;
                            if (rModel.messageType == 12 || rModel.messageType == 11)
                            {
                                rModel.NewMassage ="[自动回复]";
                            }
                        }

                        //获取房间客服未读消息数量
                        rModel.MSCount =  Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId) && x.MessageType != 10).Count();
                        dList.Add(rModel);
                    }
                */
                #endregion

                dList = dList.OrderByDescending(x => x.MSTime).ToList();


                res.Data = dList;

            }

            return res;
        }

        /// <summary>
        /// 后台——获取聊天记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<ChatLogDTO>> GetTheChatLogListAsync(PageInput<GetCSChatLogsInput> input)
        {
            PageResult<ChatLogDTO> res = new PageResult<ChatLogDTO>();
            res.Total = 0;
            res.Data = new List<ChatLogDTO>();

            var search = input.Search;
            if (search.PClassId >=0 && !search.ConsumeServerId.IsNullOrEmpty() && !search.CharRoomId.IsNullOrEmpty())
            {

                //获取消息记录
                var mlist = await (from a in Service.GetIQueryable<ChatContent>()
                             .Where(m => ((m.MessageType == 10 && m.ReceiverId.Equals(search.ConsumeServerId)) || m.MessageType != 10)&&  m.RoomId.Equals(search.CharRoomId))
                             .WhereIf(s => s.CreateTime >= search.StartTime, search.StartTime.HasValue)
                             .WhereIf(s => s.CreateTime < search.EndTime, search.EndTime.HasValue)
                                    join b in GetIQueryable() on a.RoomId equals b.Id
                             join c in Service.GetIQueryable<ChatRoomCSUser>() on b.Id equals c.RoomId
                             select a).OrderByDescending(m => m.CreateTime).ToListAsync();

                res.Total = mlist.Count;
                int skipCount = input.PageRows * (input.PageIndex - 1);
                var msList = mlist.Skip(skipCount).Take(input.PageRows).ToList();

                //获取客服信息
                var csList = await (from a in Service.GetIQueryable<Base_User>()
                                     join b in Service.GetIQueryable<ConsumeServer>() on a.Id equals b.UserId into ab
                                     from b in ab.DefaultIfEmpty()
                                     join c in Service.GetIQueryable<ChatRoomCSUser>() on b.UserId equals c.ConstmeServerId
                                     join d in GetIQueryable().Where(s => s.Id.Equals(search.CharRoomId)) on c.RoomId equals d.Id
                                     select new
                                     {
                                         a.Id,
                                         a.RealName,
                                         b.HeadImg,
                                         HeadType = 0
                                     }).ToListAsync();

                foreach (var item in msList)
                {
                    ChatLogDTO mModel = new ChatLogDTO();
                    mModel.Id = item.Id;
                    mModel.createTime = item.CreateTime;
                    mModel.createTimes = mModel.createTime.ToString("yyyy年MM月dd日 HH:mm:ss");
                    if (item.SenderType == 0)
                    {
                        mModel.userType  = item.SenderType;
                        var uModel = await Service.GetIQueryable<BTB_StaffUser>().Where(m => m.id.Equals(item.SenderId)).FirstOrDefaultAsync();
                        if (uModel != null)
                        {
                            mModel.headPortrait = uModel.HeadPortrait.IsNullOrEmpty() ? userDefaultHeadImg : uModel.HeadPortrait;
                            mModel.headImgType = uModel.HeadPortrait.IsNullOrEmpty() ? 1 : uModel.HeadType;
                            mModel.nickName = uModel.NickName;
                            mModel.nickNames = uModel.NickName;
                        }
                        else
                        {
                            mModel.headPortrait = userDefaultHeadImg;
                            mModel.headImgType = 0;
                            mModel.headImgType = 0;
                            mModel.nickName = "游客" + item.SenderId.Substring(item.SenderId.Length - 5);
                            mModel.nickNames ="游客" + item.SenderId.Substring(item.SenderId.Length - 5);
                        }

                    }
                    else
                    {
                        mModel.userType  =  item.SenderType;
                        if (!item.SenderId.IsNullOrEmpty())
                        {
                            var csMdoel = csList.Where(s => s.Id.Equals(item.SenderId)).FirstOrDefault();

                            if (!csMdoel.IsNullOrEmpty())
                            {
                                string sPath = GetServicePath();
                                mModel.headPortrait =sPath + "/" + (csMdoel.HeadImg.IsNullOrEmpty() ? KfDefaultHeadImg : csMdoel.HeadImg);
                                mModel.headImgType = 1;
                                mModel.nickName = csMdoel.RealName;
                                mModel.nickNames = csMdoel.RealName;
                            }
                        }
                        else
                        {
                            string sPath = GetServicePath();
                            mModel.headPortrait = sPath + "/" + KfDefaultHeadImg;
                            mModel.headImgType = 1;
                            if (!item.SenderId.IsNullOrEmpty())
                            {
                                mModel.nickName = "客服" + item.SenderId.Substring(item.SenderId.Length - 5);
                                mModel.nickNames ="客服" + item.SenderId.Substring(item.SenderId.Length - 5);
                            }
                            else
                            {
                                mModel.nickName = "系统";
                                mModel.nickNames = "系统";
                            }
                        }
                    }

                    mModel.messageContent = item.MessageContent;
                    mModel.messageType = item.MessageType;

                    //自动回复整理内容
                    if (mModel.messageType == 11 && !item.MessageContent.IsNullOrEmpty())
                    {
                        var rpModel = (from a in Service.GetIQueryable<Base_AutoReply>().Where(s => s.Id.Equals(item.MessageContent))
                                       select new AutoReplyDTO
                                       {
                                           id = a.Id,
                                           contents = a.Contents,
                                           imgURL = a.ImgURL,
                                           link = a.ImgURL,
                                           childList = (from b in Service.GetIQueryable<Base_AutoReplyDetail>(true).Where(s => s.ReplyId.Equals(a.Id))
                                                        select new ReplyDetailDTO
                                                        {
                                                            id = b.Id,
                                                            contents = b.KeyNum,
                                                            imgURL = b.ImgUrl,
                                                            link = b.LinkUrl
                                                        }).ToList()
                                       }).FirstOrDefault();
                        if (!rpModel.IsNullOrEmpty())
                        {
                            mModel.auto_Model = rpModel;
                        }


                    }
                    else if (mModel.messageType == 12 && !item.MessageContent.IsNullOrEmpty())
                    {
                        var dtMdoel = Service.GetIQueryable<Base_AutoReplyDetail>().Where(x => x.Id.Equals(item.MessageContent))
                                      .Select(s => new Base_AutoReplyDetailDTO { 
                                        id = s.Id,
                                        createTime = s.CreateTime,
                                        replyId = s.ReplyId,
                                        contents = s.Contents
                                      }).FirstOrDefault();
                        if (!dtMdoel.IsNullOrEmpty())
                        {
                            mModel.detailModel = dtMdoel;
                        }
                        else
                        {
                            mModel.messageType = 1;
                            mModel.messageContent = "抱歉，未找到对应内容";
                            Service.Update(mModel);
                        }
                    }

                    mModel.messageSize = item.MessageSize;
                    mModel.messageName = item.MassageName;
                    mModel.vstate = item.VState;

                    res.Data.Add(mModel);
                }

                 
            }

            return res;
        }

        public ChatBigScreenData GetBigScreenData(GetBSInput input)
        {
            ChatBigScreenData res = new ChatBigScreenData();

            DateTime? STime = null;
            DateTime? ETime = null;

            if (input.Year.HasValue && input.Month.HasValue)
            {
                STime = DateTime.Parse(input.Year.Value.ToString("0000") + "-" + input.Month.Value.ToString("00") + "-01");
                ETime = STime.Value.AddMonths(1);
            }
            else if (input.Year.HasValue)
            {
                STime = DateTime.Parse(input.Year.Value.ToString("0000") + "-01-01");
                ETime = STime.Value.AddYears(1);
            }

            res.NameList = new List<string>();
            res.DataList = new List<int>();

            //商城咨询量
            res.NameList.Add("商城咨询量");
            int cpCount = Service.GetIQueryable<ChatRoom>().Where(s => s.ClassId == 0).WhereIf(s => s.CreateTime >= STime, STime.HasValue)
                             .WhereIf(s => s.CreateTime < ETime, ETime.HasValue).Count();
            res.DataList.Add(cpCount);

            //爱学咨询量
            res.NameList.Add("爱学咨询量");
            int qsCount = Service.GetIQueryable<ChatRoom>().Where(s => s.ClassId == 1).WhereIf(s => s.CreateTime >= STime, STime.HasValue)
                             .WhereIf(s => s.CreateTime < ETime, ETime.HasValue).Count();
            res.DataList.Add(qsCount);


            //书房咨询量
            res.NameList.Add("书房咨询量");
            int rmCount = Service.GetIQueryable<ChatRoom>().Where(s => s.ClassId == 2).WhereIf(s => s.CreateTime >= STime, STime.HasValue)
                             .WhereIf(s => s.CreateTime < ETime, ETime.HasValue).Count();
            res.DataList.Add(rmCount);

            return res;
        }

        #endregion

        #region 私有成员
        private int GetChatUserSumData(int type)
        {
            DateTime theTime = DateTime.Now;
            DateTime STime = DateTime.Parse(theTime.ToString("yyyy-MM-dd"));
            DateTime ETime = STime.AddDays(1);
            if (type == 1) //近七天
            {
                ETime = STime;
                STime = ETime.AddDays(-7);
            }
            else if (type == 2) //本月
            {
                ETime = STime;
                STime = DateTime.Parse(ETime.ToString("yyyy-MM-01"));
            }
            else if (type == 3) //半年
            {
                ETime = STime;
                if (ETime.Month < 7)
                {
                    STime = DateTime.Parse(ETime.ToString("yyyy-01-01"));
                }
                else
                {
                    STime = DateTime.Parse(ETime.AddMonths(-6).ToString("yyyy-MM-dd"));
                }
            }
            else if (type == 4) //今年
            {
                ETime = STime;
                STime = DateTime.Parse(ETime.ToString("yyyy-01-01"));
            }

            var aCount = Service.GetIQueryable<UserChatLog>().Where(s => s.ChatDate >= STime && s.ChatDate < ETime).Count();

            return aCount;
        }

        /// <summary>
        /// 获取网站部署地址
        /// </summary>
        /// <returns></returns>
        private string GetServicePath()
        {
            var sPath = ConfigurationUtil.GetSection("ServiceURL");

            return sPath;
        }
        #endregion
    }
}